package net.sxnic.item.ucenter;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javassist.NotFoundException;
import net.sxinfo.core.dao.Page;
import net.sxinfo.core.dao.hibernate3.HibernateCriteria;
import net.sxnic.comm.utils.CommUtils;
import net.sxnic.item.ItemConstants;
import net.sxnic.ugr.dept.Dept;
import net.sxnic.ugr.dept.dao.DeptDao;
import net.sxnic.ugr.group.Group;
import net.sxnic.ugr.group.dao.GroupDao;
import net.sxnic.ugr.menu.Menu;
import net.sxnic.ugr.menu.dao.MenuDao;
import net.sxnic.ugr.menu.util.MenuComparator;
import net.sxnic.ugr.role.Role;
import net.sxnic.ugr.role.dao.RoleDao;
import net.sxnic.ugr.user.User;
import net.sxnic.ugr.user.UserDisabledException;
import net.sxnic.ugr.user.UserNotExistsException;
import net.sxnic.ugr.user.WrongPasswordException;
import net.sxnic.ugr.user.dao.UserDao;
import net.sxnic.ugr.website.Website;
import net.sxnic.ugr.website.dao.WebsiteDao;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * 用户中心本地实现类
 * 
 * @author yfsun
 * 
 */
@Service("ucService")
public class LocalUcenterServiceImpl implements UcenterService {

	private static Logger logger = LoggerFactory
			.getLogger(LocalUcenterServiceImpl.class);

	@Autowired
	private UserDao userManager;

	@Autowired
	private DeptDao deptManager;

	@Autowired
	private WebsiteDao wsManager;

	@Autowired
	private RoleDao roleManager;

	@Autowired
	private MenuDao menuManager;

	@Autowired
	private GroupDao groupManager;

	@Override
	public User login(String userName, String password)
			throws UserNotExistsException, UserDisabledException,
			WrongPasswordException {
		if (StringUtils.isBlank(userName) || StringUtils.isBlank(password)) {
			return null;
		}

		User user = userManager.findByUnique("username", userName);

		// 验证有无此用户，并验证UserName大小写
		if (user == null || !userName.equals(user.getUsername())) {
			throw new UserNotExistsException();
		}

		if (!user.getEnabled()) {
			throw new UserDisabledException();
		}

		// 如果密码不匹配
		if (!DigestUtils.md5Hex(password).equals(user.getPassword())) {
			throw new WrongPasswordException();
		}

		user.setLastLoginDate(new Date());
		userManager.save(user);

		return user;
	}

	@Override
	public void updateUser(User user) {
		if (user != null) {
			userManager.update(user);
		}
	}

	@Override
	public User findUserByUserName(String userName) {
		return userManager.findByUnique("username", userName);
	}

	@Override
	public List<Website> findWebSitesByUserName(String userName) {
		User user = userManager.findByUnique("username", userName);
		if (user == null) {
			return null;
		}

		// 先找用户表定义的子站点
		String[] ws_s = StringUtils.split(user.getSiteCodes(), ",");
		Set<String> wsSet = CommUtils.ArraytoSet(ws_s);

		List<Website> list = new ArrayList<Website>();
		for (String temp : wsSet) {
			list.add(wsManager.findByUnique("code", temp));
		}

		return list;
	}

	@Override
	public List<Menu> findMenusByUserName(String userName) {

		Set<Role> rSet = findRolesByUserName(userName);

		if (rSet == null || rSet.size() <= 0) {
			return null;
		}

		List<Menu> setList = new ArrayList<Menu>();

		for (Role r : rSet) {
			for (Menu m : r.getMenus()) {
				if (!setList.contains(m)) {
					setList.add(m);
				}
			}
		}

		// 排序处理
		MenuComparator comparator = new MenuComparator();

		Collections.sort(setList, comparator);

		List<Menu> mSet = new ArrayList<Menu>();
		for (Menu m : setList) {

			mSet.add(m);
		}
		return mSet;
	}

	@Override
	public boolean canVerifyCatalogByUserName(String userName, String catalog1,
			String catalog2) {
		return false;
	}

	@Override
	public Set<Role> findRolesByUserName(String userName) {
		User u = userManager.findByUnique("username", userName);

		if (u == null)
			return null;

		Set<Role> roles = u.getRoles();

		for (Group g : u.getGroups()) {
			for (Role r : g.getRoles()) {
				if (!roles.contains(r)) {
					roles.add(r);
				}
			}
		}
		return roles;
	}

	@Override
	public Dept findDeptByCode(String deptCode) {
		return deptManager.findByUnique("code", deptCode);
	}

	@Override
	public Dept getDeptById(String id) {
		return deptManager.get(id);
	}

	@Override
	public void saveDept(Dept dept) {
		deptManager.save(dept);
	}

	@Override
	public Role getRoleById(String id) {
		return roleManager.get(id);
	}

	@Override
	public Role getRoleByCode(String code) {
		return roleManager.findByUnique("role", code);
	}

	@Override
	public void saveRole(Role role) {
		roleManager.save(role);
	}

	@Override
	public Group getGroupById(String id) {
		return groupManager.get(id);
	}

	@Override
	public Group getGroupByCode(String code) {
		return groupManager.findByUnique("group", code);
	}

	@Override
	public void saveGroup(Group group) {
		groupManager.save(group);
	}

	@Override
	public Menu getMenuById(String id) {
		return menuManager.get(id);
	}

	@Override
	public Menu getMenuByCode(String code) {
		return menuManager.findByUnique("code", code);
	}

	@Override
	public void saveMenu(Menu menu) {
		menuManager.save(menu);
	}

	@Override
	public Page getDeptPage(int page, int pageSize, HibernateCriteria hc) {
		return deptManager.getPageByCriteria(page, pageSize, hc);
	}

	@Override
	public Page getRolePage(int page, int pageSize, HibernateCriteria hc) {
		return roleManager.getPageByCriteria(page, pageSize, hc);
	}

	@Override
	public Page getGroupPage(int page, int pageSize, HibernateCriteria hc) {
		return groupManager.getPageByCriteria(page, pageSize, hc);
	}

	@Override
	public Page getMenutPage(int page, int pageSize, HibernateCriteria hc) {
		return menuManager.getPageByCriteria(page, pageSize, hc);
	}

	@Override
	public boolean isUserInRole(User user, Role role) {
		if (user == null || !user.getEnabled()) {
			logger.debug("==用户{}不可用，isUserInRole方法返回false===",
					user.getUsername());
			return false;
		}

		if (user.getRoles().contains(role)) {
			return true;
		}

		return false;
	}

	@Override
	public boolean isUserInRole(User user, String role) {
		if (user == null || !user.getEnabled()) {
			logger.debug("==用户{}不可用，isUserInRole方法返回false===",
					user.getUsername());
			return false;
		}

		if (user.getRoles().contains(getRoleByCode(role))) {
			return true;
		}

		return false;
	}

	@Override
	public boolean isUserInRole(User user, String... roles) {
		if (user == null || !user.getEnabled()) {
			logger.debug("==用户{}不可用，isUserInRole方法返回false===",
					user.getUsername());
			return false;
		}

		for (String role : roles) {
			if (user.getRoles().contains(getRoleByCode(role))) {
				return true;
			}
		}

		return false;
	}

	@Override
	public String findTaskAssignee(User user) throws NotFoundException {

		if (user == null || !user.getEnabled()) {
			logger.error("==用户{}不可用，findTaskAssignee方法返回null===",
					user.getUsername());
			return "";
		}

		if (isUserInRole(user, ItemConstants.APPROVER_ROLE)) {
			return user.getUsername();
		}
		if (isUserInRole(user, ItemConstants.ZZDW_ROLE)) {
			return user.getDept().getCode();
		}
		if (isUserInRole(user, ItemConstants.GLDW_ROLE)) {
			if(user.getDept().getParent()==null){
				return user.getDept().getCode();
			}else{
				return user.getDept().getParent().getCode();
			}
		}

		return "";
		//throw new NotFoundException("===没有找到指定用户的所在单位的TaskAssignee====");
	}

	@Override
	public String findTaskAssignee(Dept dept) throws NotFoundException {
//		List<User> users = findUsersByDept(dept);
//
//		for (User u : users) {
//			if (isUserInRole(u, ItemConstants.APPROVER_ROLE)) {
//				return u.getUsername();
//			}
//		}
		return dept.getCode();

		//throw new NotFoundException("===没有找到指定用户的所在单位的TaskAssignee====");
	}

	@Override
	public List<User> findUsersByDept(Dept dept) {
		return userManager.findBy("dept", dept);
	}

	@Override
	public List<Dept> findDeptsByUser(User user) {
		return deptManager.findByUser(user);
	}

	@Override
	public Map<String, String> findUserMenus(String userName) {
		
		Map<String, String> map = new HashMap<String, String>();
		Set<Menu> menus =  findMenus (userName);
		 
		if (menus!=null && menus.size() > 0) {
			for (Menu menu : menus) {
				map.put(menu.getCode(), menu.getValue());
			}
		} else {
			return null;
		}

		return map;
	}
	
	@SuppressWarnings("unchecked")
	public Set<Menu> findMenus(String userName) {
		Set<Role> rSet = findUsersRole(userName);

		if (rSet == null || rSet.size() <= 0) {
			return null;
		}

		List<Menu> setList = new ArrayList<Menu>();

		for (Role r : rSet) {
			for (Menu m : r.getMenus()) {
				if (!setList.contains(m)) {
					setList.add(m);
				}
			}
		}

		// 排序处理
		MenuComparator comparator = new MenuComparator();

		Collections.sort(setList, comparator);

		Set<Menu> mSet = new LinkedHashSet<Menu>();
		for (Menu m : setList) {
			mSet.add(m);
		}
		return mSet;		 
	}
	
	public Set<Role> findUsersRole(String userName) {
		User u = userManager.findByUnique("username", userName);
		
		if (u == null)
			return null;

		 

		Set<Role> roles = u.getRoles();

		for (Group g : u.getGroups()) {
			for (Role r : g.getRoles()) {
				if (!roles.contains(r)) {
					roles.add(r);
				}
			}
		}
		return roles;
	}

	@Override
	public List<Menu> getTopLevelMenus() {
		return menuManager.getTopLevel();
	}

	@Override
	public List<Menu> getSubLevel(String parentMenuCode) {
		return menuManager.getSubLevel(parentMenuCode);
	}

}
